#pragma once

//struct ShapeModule
//{
//
//};

enum class ParticleType : std::uint32_t
{
    kEmit = 1,
    kNormal
};

class ParticleSystem
{
public:
    ParticleSystem(ID3D11Device& device3D, std::uint32_t maxParticles);
    void SetMaxAge(float maxAge);
    void SetPosition(const DirectX::XMFLOAT3& position);
    void SetBillboard(wrl::ComPtr<ID3D11ShaderResourceView> billboard);
    //nowTime 
    void Update(float nowTime, float timeElapsed);
    void Draw(DX::DeviceResources& deviceResources, ID3D11DeviceContext& context3D, const Camera& camera);
    void SetBumpInterval(float interval);

private:
    void CreateRandomTexture(ID3D11Device& device);
    void CreateInitialEmitter(ID3D11Device& device);
    void CreateParticleBuffers(ID3D11Device& device);
    void CreateShaders(ID3D11Device& device);
    void CreateInputLayouts(ID3D11Device& device);
    void CreateConstantBuffers(ID3D11Device& device);
    void UpdateConstantBuffers(ID3D11DeviceContext& context3D, const Camera& camera);
    void CreateSamplers(ID3D11Device& device);
    void SetupGenerationGS(ID3D11DeviceContext& context3D);
    void SetupExpansionGS(ID3D11DeviceContext& context3D);
    void SetupRenderingPS(ID3D11DeviceContext& context3D);
    void SetupRenderingVS(ID3D11DeviceContext& context3D);
    void CreateAlphaBlendingState(ID3D11Device& device);

    wrl::ComPtr<ID3D11Texture1D> m_randomTexture;
    wrl::ComPtr<ID3D11ShaderResourceView> m_randomTexSrv;
    wrl::ComPtr<ID3D11Buffer> m_particleBuffer1, m_particleBuffer2, m_initialParticle;
    wrl::ComPtr<ID3D11GeometryShader> m_particleGenerationShader,
        m_particleExpandingShader;
    wrl::ComPtr<ID3D11VertexShader> m_forwardingVS, m_expandingVS;
    wrl::ComPtr<ID3D11PixelShader> m_samplingPS;
    wrl::ComPtr<ID3D11ShaderResourceView> m_billboard;
    wrl::ComPtr<ID3D11InputLayout> m_particleInputLayout;
    wrl::ComPtr<ID3D11Buffer> m_particleExpansionGSViewCb;
    wrl::ComPtr<ID3D11Buffer> m_particleGenerationGSPerFrameCb, m_particleGenerationFixedCb;
    wrl::ComPtr<ID3D11Buffer> m_particleRenderingVSFixedCb;
    wrl::ComPtr<ID3D11DepthStencilState> m_disableDepthStencilState;
    wrl::ComPtr<ID3D11SamplerState> m_linearWrapSampler, m_linearClampSampler;
    wrl::ComPtr<ID3D11BlendState> m_alphaBlending;
    DirectX::XMFLOAT3 m_position;
    float m_now;
    float m_age;
    std::uint32_t m_maxParticles;
    float m_bumpInterval;
    bool m_firstRun;
    float m_timeElapsed;
};